import parole
from parole.colornames import colors
from parole.display import interpolateRGB
import pygame, random
from pprint import pprint

import sim, interface
from util import *

def makeTown():
    mbox = interface.messageBox('Welcome to the village of Anoiktos...')
    parole.display.update()

    # Create map 
    COLS, ROWS = 96, 51
    map = parole.map.Map2D('The village of caconyction', (COLS, ROWS))

    # Populate map with objects

    # Grass (cellular automata)
    grassGenerator = \
        lambda bg_rgb: parole.map.MapObjectGenerator("grassGenerator",
            lambda: sim.Obj('grass', -200, 
                parole.map.AsciiTile(' ',#random.choice([' ']*3 + [',',';',"'", '"']),
                (random.randint(0,64),random.randint(96,160),random.randint(0,64)),
                bg_rgb=bg_rgb), massNoun=True))
    grassColor = colors['DarkGreen']
    sandColor = colors['Olive']
    grassConditions = {
        0: grassGenerator(interpolateRGB(sandColor, grassColor, 0.0)),
        1: grassGenerator(interpolateRGB(sandColor, grassColor, 0.1)),
        2: grassGenerator(interpolateRGB(sandColor, grassColor, 0.2)),
        3: grassGenerator(interpolateRGB(sandColor, grassColor, 0.3)),
        4: grassGenerator(interpolateRGB(sandColor, grassColor, 0.4)),
        5: grassGenerator(interpolateRGB(sandColor, grassColor, 0.5)),
        6: grassGenerator(interpolateRGB(sandColor, grassColor, 0.6)),
        7: grassGenerator(interpolateRGB(sandColor, grassColor, 0.8)),
        8: grassGenerator(interpolateRGB(sandColor, grassColor, 0.9)),
        9: grassGenerator(interpolateRGB(sandColor, grassColor, 1.0))
    }
    grassAreaGenerator =  parole.map.CellularAutomataGenerator("grassAreaGenerator",
            0.90, grassConditions, seedEdges=True)
    grassAreaGenerator.apply(map)

    # Flowers (cellular automata)
    baseRoseR, baseRoseG, baseRoseB = colors['DarkRed']
    roseGenerator = parole.map.MapObjectGenerator("roseGenerator",
            lambda: sim.Obj('flower', -2,
                parole.map.AsciiTile('*', (baseRoseR + random.randint(-64,64),
                                           baseRoseG, baseRoseB))))
    roseConditions = {
        # num neighbors   # generator
        6: roseGenerator,
        7: roseGenerator,
        8: roseGenerator,
        9: roseGenerator
    }
    roseAreaGenerator = parole.map.CellularAutomataGenerator("roseGenerator",
            0.35, roseConditions) 
    roseAreaGenerator.apply(map)

    # Trees
    baseTreeRGB = colors['ForestGreen']
    autumnTreeRGB = colors['Gold']
    treeGenerator = parole.map.MapObjectGenerator('treeGenerator',
            lambda: sim.Obj('tree', 50, parole.map.AsciiTile('^',
                interpolateRGB(baseTreeRGB, autumnTreeRGB, max(0.0, min(1.0,
                    random.normalvariate(0.33, 0.3))))), blockLOS=True,
                blockMove=True))
    forestConditions = {
        5: treeGenerator,
        6: treeGenerator,
        7: treeGenerator,
        8: treeGenerator,
        9: treeGenerator,
    }
    forestGenerator = parole.map.CellularAutomataGenerator("forestGenerator",
            0.25, forestConditions)
    forestGenerator.apply(map)

    # Road (cellular automata)
    baseRoadR, baseRoadG, baseRoadB = colors['SaddleBrown']
    roadGenerator = \
        lambda n: parole.map.MapObjectGenerator("roadGenerator",
            lambda: sim.Obj('dirt road', -3,
                parole.map.AsciiTile(random.choice([' ']*5 + ['.',"'"]), 
                    colors['SaddleBrown'],
                    bg_rgb=(baseRoadR-(n)*5+random.randint(00,00),
                            baseRoadG-(n)*5+random.randint(00,00),
                            baseRoadB-(n)*5+random.randint(00,00)))))
    roadConditions = {
        3: roadGenerator(3),
        4: roadGenerator(4),
        5: roadGenerator(5),
        6: roadGenerator(6),
        7: roadGenerator(7),
        8: roadGenerator(8),
        9: roadGenerator(9)
    }
    roadAreaGenerator = parole.map.CellularAutomataGenerator("roadGenerator",
            0.50, roadConditions, seedEdges=True, clearFirst=True)
    # road stretches across map centered at y=32, with a height of 5
    roadRect = pygame.Rect((0,30), (COLS,5))
    roadAreaGenerator.apply(map, roadRect)

    # object generators for the inn
    floorGenerator = parole.map.MapObjectGenerator("floorGenerator", 
            lambda: sim.Obj('sawdust-covered floor', 10, parole.map.AsciiTile('.',
                colors['Gray'], bg_rgb=colors['DarkKhaki'])), clearFirst=True)
    wallGenerator = parole.map.MapObjectGenerator("wallGenerator", 
            lambda: sim.Obj('wooden wall', 100, parole.map.AsciiTile('#',
                colors['Sienna'], bg_rgb=colors['Sienna']), blockLOS=True,
                blockMove=True), clearFirst=True)
    doorGenerator = parole.map.MapObjectGenerator("doorGenerator", 
            lambda: sim.Door('door', 100, parole.map.AsciiTile('/',
                colors['White'], bg_rgb=None), parole.map.AsciiTile('+',
                    colors['White'])))
    stairsUpGenerator = parole.map.MapObjectGenerator("stairsDownGenerator", 
            lambda: sim.Obj('inaccessible stairway leading up', 100,
                parole.map.AsciiTile('<', colors['White'],
                    bg_rgb=None), startsVowel=True))
    tapGenerator = parole.map.MapObjectGenerator("tapGenerator", 
            lambda: sim.Obj('draft beer tap', 100, parole.map.AsciiTile('&',
                colors['Silver'], bg_rgb=colors['SaddleBrown']),
                blockMove=True), clearFirst=True)
    barGenerator = parole.map.MapObjectGenerator("barGenerator", 
            lambda: sim.Obj('varnished oak bar', 100, parole.map.AsciiTile('=',
                colors['SaddleBrown'], bg_rgb=colors['SaddleBrown']),
                blockMove=True), clearFirst=True)
    tableGenerator = parole.map.MapObjectGenerator("tableGenerator", 
            lambda: sim.Obj('pine table', 100, parole.map.AsciiTile('O',
                colors['SaddleBrown'], bg_rgb=None), blockMove=True))
    chairGenerator = parole.map.MapObjectGenerator("chairGenerator", 
            lambda: sim.Obj('pine chair', 100, parole.map.AsciiTile('h',
                colors['SaddleBrown'], bg_rgb=None)))
    windowGenerator = parole.map.MapObjectGenerator("windowGenerator", 
            lambda: sim.Obj('glass window', 100, parole.map.AsciiTile(' ',
                colors['PaleTurquoise'], bg_rgb=colors['PaleTurquoise']),
                blockLOS=False, blockMove=True), clearFirst=True)
    drunkGenerator = parole.map.MapObjectGenerator("", 
            lambda: sim.Obj('fitfully sleeping drunk', 100,
                parole.map.AsciiTile('@', colors['DarkBlue']), blockLOS=False,
                blockMove=True), clearFirst=False)

    # The Inn
    innTemplate = \
"""
###############
#            <#
#====&==== d  -
# h h h h     #
+      h      +
# h   hoh   h #
-hoh   h   hoh-
# h         h #
##-##-#+#-##-##
"""[1:]
    innLegend = {  
            '#': wallGenerator,
            '+': doorGenerator,
            '<': stairsUpGenerator,
            '=': barGenerator,
            '&': tapGenerator,
            'o': tableGenerator,
            'h': chairGenerator,
            '-': windowGenerator,
            'd': drunkGenerator,
        }
    innH, innW = len(innTemplate.splitlines()), len(innTemplate.splitlines()[0])
    innGenerator = parole.map.TemplateGenerator("innGenerator",
            innTemplate, innLegend, backgroundGen=floorGenerator,
            clearFirst=False)
    innRect = pygame.Rect((25,12), (15,9))
    map.applyGenerator(innGenerator, innRect)

    # Generators for the mine entrance
    stoneGenerator = parole.map.MapObjectGenerator("stoneGenerator", 
            lambda: sim.Obj('stone outcropping', 100, 
                parole.map.AsciiTile(' ',
                (0,0,0),
                bg_rgb=interpolateRGB(colors['Gray'], colors['Silver'], max(0.0,
                    min(1.0, random.normalvariate(0.33, 0.3))))), blockLOS=True,
                blockMove=True), clearFirst=True)
    mineshaftGenerator = parole.map.MapObjectGenerator("mineshaftGenerator", 
            lambda: sim.Obj('gaping mineshaft into the earth, charred and '
                'stained with yellow', 100,
                parole.map.AsciiTile('>', 
                    colors['Yellow'],
                    bg_rgb=(0,0,0)
                )), clearFirst=True)
    hatchGenerator = parole.map.MapObjectGenerator("hatchGenerator", 
            lambda: sim.Door('solid chondrite hatch', 100,
                parole.map.AsciiTile('/', colors['Silver'],
                    bg_rgb=colors['Gray']),parole.map.AsciiTile('+',
                        colors['Silver'], bg_rgb=colors['Gray'])))
    dirtGenerator = parole.map.MapObjectGenerator("dirtGenerator", 
            lambda: sim.Obj('barren earth', 100,
                parole.map.AsciiTile('.', (244 + random.randint(-25,25),
                                           164 + random.randint(-12,12),
                                           96 + random.randint(-8,8)),
                    bg_rgb=(205 + random.randint(-10,10),
                            133 + random.randint(-7,7),
                            63 + random.randint(-4,4))
                    ), massNoun=True), clearFirst=True)

    # Entrance to the mines
    entranceTemplate = \
"""
  ###   ##
 ##.##   ##     #
 #.>.### #     # 
 ##...### #     ##
##...### #     ##
 ##...### #     ##
###...###  ##
 ###..##   ###
  ##.#####  ###
   #+##    ##
"""[1:]
    entranceLegend = {
                '#': stoneGenerator,
                '>': mineshaftGenerator,
                '.': dirtGenerator,
                '+': hatchGenerator,
            }
    entranceGenerator = parole.map.TemplateGenerator("entranceGenerator",
            entranceTemplate, entranceLegend)
    entranceRect = pygame.Rect((65,7), (18,10))
    map.applyGenerator(entranceGenerator, entranceRect)

    # Trail generator
    baseTrailR, baseTrailG, baseTrailB = colors['SandyBrown']
    trailGenerator = \
        lambda n: parole.map.MapObjectGenerator("trailGenerator",
            lambda: sim.Obj('dirt trail', -3,
                parole.map.AsciiTile(random.choice([' ']*5 + ['.',"'"]), 
                    colors['SandyBrown'],
                    bg_rgb=(baseTrailR-(n)*5+random.randint(00,00),
                            baseTrailG-(n)*5+random.randint(00,00),
                            baseTrailB-(n)*5+random.randint(00,00)))))
    trailConditions = {
        3: trailGenerator(3),
        4: trailGenerator(4),
        5: trailGenerator(5),
        6: trailGenerator(6),
        7: trailGenerator(7),
        8: trailGenerator(8),
        9: trailGenerator(9)
    }
    trailAreaGenerator = parole.map.CellularAutomataGenerator("trailGenerator",
            0.35, trailConditions, seedEdges=True, clearFirst=True)

    # link inn, entrance, and shop to road with trails
    innTrailRect = pygame.Rect((0,0), (3, roadRect.top - innRect.bottom))
    innTrailRect.top = innRect.bottom
    innTrailRect.centerx = innRect.centerx
    trailAreaGenerator.apply(map, innTrailRect)

    entranceTrailRect = pygame.Rect((0,0), (3, roadRect.top - entranceRect.bottom))
    entranceTrailRect.top = entranceRect.bottom
    entranceTrailRect.centerx = entranceRect.centerx - 5
    trailAreaGenerator.apply(map, entranceTrailRect)


    # perlin water
    #waterGenerator = parole.map.PerlinGenerator("waterGenerator",
    #        lambda t, n: sim.Obj('some water', 0,
    #        parole.map.AsciiTile(' ', colors['White'],
    #            bg_rgb=interpolateRGB(colors['RoyalBlue'],
    #                colors['LightBlue'], n))),
    #        lambda t, r: float(t.col - r.x) / r.w,
    #        lambda t, r: float(t.row - r.y) / r.h,
    #        lambda t, r: random.random(), clearFirst=True)
    #map.applyGenerator(waterGenerator, pygame.Rect((25, 35), (20, 20)))
    #data['waterGenerator'] = waterGenerator

    map.setAmbientLight((255,255,255), 0.3)

    brazier = parole.map.LightSource((255,255,255), 5.0)
    brazier.apply(map, (27,14))
    brazier.copy().apply(map, (27,18))
    brazier.copy().apply(map, (37,14))
    brazier.copy().apply(map, (37,18))
    brazier.copy().apply(map, (32,16))

    map.update()
    parole.display.scene.remove(mbox)
    parole.display.update()
    return map, (2,32), (68, 9) # return map and player starting pos


